//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.vere.orm.db.pool;

import com.vere.orm.db.Configuration;
import com.vere.orm.model.ConnectionItem;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

public class PooledConnection extends ConnectionPool {
    private static int idleSize = 5;
    private static int maxSize = 10;
    private static long waitTime = 10000L;
    private static long checkTime = 10000L;
    private static List<ConnectionItem> idleConnectionList;
    private static List<ConnectionItem> activeConnectionList;

    static {
        if (idleConnectionList == null && activeConnectionList == null) {
            try {
                Class.forName(Configuration.getDataSourcePropery("dbDriver"));
            } catch (ClassNotFoundException var1) {
                var1.printStackTrace();
            }
        }

    }

    public PooledConnection() {
        if (idleConnectionList == null && activeConnectionList == null) {
            this.init();
            Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
                public void run() {
                    PooledConnection.this.destroyAll();
                }
            }));
        }

    }

    private void init() {
        synchronized(this) {
            idleConnectionList = new ArrayList();
            activeConnectionList = new ArrayList();
            idleSize = Integer.parseInt(Configuration.getDataSourcePropery("idleSize"));
            maxSize = Integer.parseInt(Configuration.getDataSourcePropery("maxSize"));
            waitTime = Long.parseLong(Configuration.getDataSourcePropery("waitTime"));
            checkTime = Long.parseLong(Configuration.getDataSourcePropery("checkTime"));

            for(int i = 0; i < idleSize; ++i) {
                ConnectionItem connectionItem = createConnection();
                if (connectionItem != null) {
                    idleConnectionList.add(connectionItem);
                }
            }

        }
    }

    private static ConnectionItem createConnection() {
        ConnectionItem connectionItem = null;
        Connection conn = null;

        try {
            conn = DriverManager.getConnection(Configuration.getDataSourcePropery("dbUrl"), Configuration.getDataSourcePropery("dbUsername"), Configuration.getDataSourcePropery("dbPassword"));
        } catch (SQLException var3) {
            var3.printStackTrace();
        }

        if (conn != null) {
            connectionItem = new ConnectionItem();
            connectionItem.setActiveStartTime(System.currentTimeMillis());
            connectionItem.setConnection(conn);
        }

        return connectionItem;
    }

    public void close(Connection conn, ResultSet rs) throws SQLException {
        if (conn != null) {
            synchronized(this) {
                int hashCode = conn.hashCode();
                ConnectionItem connectionItem = this.removeActiveConnectionItem(hashCode);
                if (connectionItem != null) {
                    if (this.isValid(connectionItem.getConnection())) {
                        if (!connectionItem.getConnection().getAutoCommit()) {
                            connectionItem.getConnection().rollback();
                        }

                        if (idleConnectionList.size() < idleSize) {
                            idleConnectionList.add(connectionItem);
                            this.notifyAll();
                        } else {
                            destroyConnection(connectionItem);
                        }
                    }

                }
            }
        }
    }

    private ConnectionItem removeActiveConnectionItem(int hashCode) {
        for(int i = 0; i < activeConnectionList.size(); ++i) {
            ConnectionItem connectionItem = (ConnectionItem)activeConnectionList.get(i);
            if (connectionItem.getId() == hashCode) {
                activeConnectionList.remove(i);
                return connectionItem;
            }
        }

        return null;
    }

    public void destroyAll() {
        synchronized(this) {
            int i;
            ConnectionItem connectionItem;
            Connection conn;
            if (idleConnectionList != null) {
                for(i = 0; i < idleConnectionList.size(); ++i) {
                    connectionItem = (ConnectionItem)idleConnectionList.get(i);
                    conn = null;
                    if (connectionItem != null) {
                        conn = connectionItem.getConnection();
                    }

                    destroyConnection(connectionItem);
                }

                idleConnectionList.clear();
                idleConnectionList = null;
            }

            if (activeConnectionList != null) {
                for(i = 0; i < activeConnectionList.size(); ++i) {
                    connectionItem = (ConnectionItem)activeConnectionList.get(i);
                    conn = null;
                    if (connectionItem != null) {
                        conn = connectionItem.getConnection();

                        try {
                            if (!conn.getAutoCommit()) {
                                conn.rollback();
                            }
                        } catch (SQLException var6) {
                            var6.printStackTrace();
                        }
                    }

                    destroyConnection(connectionItem);
                }

                activeConnectionList.clear();
                activeConnectionList = null;
            }

        }
    }

    private boolean isValid(Connection conn) {
        try {
            return conn != null && !conn.isClosed() && conn.isValid(1000);
        } catch (SQLException var3) {
            var3.printStackTrace();
            return false;
        }
    }

    public Connection getConnection() throws SQLException {
        ConnectionItem connectionItem = null;
        synchronized(this) {
            if (idleConnectionList.size() > 0) {
                connectionItem = (ConnectionItem)idleConnectionList.remove(0);
                connectionItem.setActiveStartTime(System.currentTimeMillis());
            } else if (activeConnectionList.size() < maxSize) {
                connectionItem = createConnection();
            } else {
                ConnectionItem oldestActiveConnection = (ConnectionItem)activeConnectionList.get(0);
                if (System.currentTimeMillis() - oldestActiveConnection.getActiveStartTime() >= checkTime) {
                    activeConnectionList.remove(oldestActiveConnection);
                    if (!oldestActiveConnection.getConnection().getAutoCommit()) {
                        oldestActiveConnection.getConnection().rollback();
                    }

                    connectionItem = createConnection();
                    destroyConnection(oldestActiveConnection);
                } else {
                    try {
                        this.wait(waitTime);
                    } catch (InterruptedException var5) {
                        var5.printStackTrace();
                    }
                }
            }

            if (connectionItem != null) {
                activeConnectionList.add(connectionItem);
                return connectionItem.getConnection();
            } else {
                return null;
            }
        }
    }

    private static void destroyConnection(ConnectionItem connectionItem) {
        try {
            if (connectionItem != null) {
                Connection conn = connectionItem.getConnection();
                if (conn == null) {
                    conn.close();
                    conn = null;
                }

                connectionItem = null;
            }
        } catch (SQLException var2) {
            var2.printStackTrace();
        }

    }

	@Override
	public Logger getParentLogger() throws SQLFeatureNotSupportedException {
		// TODO Auto-generated method stub
		return null;
	}
}
